package org.musicsweet.interceptor;


import com.alibaba.fastjson.JSON;
import org.musicsweet.anotation.AuthReq;
import org.musicsweet.constant.GlobalConfig;
import org.musicsweet.entity.SysUser;
import org.musicsweet.result.ResultData;
import org.musicsweet.util.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

/**
 * 后台鉴权拦截器（配置哪些请求需要鉴权token获取用户信息，哪些不需要   需要鉴权的话就在上面加个注解 @AuthReq）
 * 拦截器需要
 * 标示注解@Component springBoot会自动扫描这个类
 * 并且实现springMVC中HandlerInterceptor
 * 类似于口罩-->呼吸器官-->气管-->肺部
 * 会一层层拦截有害物质
 */
@Component
public class AdminAuthInterceptor implements HandlerInterceptor {
    //在springBoot中会经常用到这个方法 会自动扫描这个类，并注册到springBoot当中 效率很高

    @Autowired
    private RedisUtil redisUtil;

    /**
     * alt+insert实现上面三个方法
     *
     * @param request
     * @param response
     * @param handler
     * @return true:请求可以继续往下走 false:请求被拦截
     * @throws Exception
     */
    //预处理（用的较多）
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        /**
         * 首先判断当前请求是加了@AuthReq，加了我们就去判断token是否有效
         * 首先将handler强转为HandlerMethod类型
         * 然后再用handlerMethod获取到getMethod
         * 通过映射的方法  method有个方法getAnnotation
         * 获取请求上面是否有@AuthReq注解
         */
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Method method = handlerMethod.getMethod();
        AuthReq authReq = method.getAnnotation(AuthReq.class);
        //判断是否有@AuthReq注解
        if (authReq != null) {
            //鉴权操作 判断token是否有效,下面的请求需要根据token获取用户信息
            //首先我们前段是用问号的方式可以进行传参数  可以使用request.getParameter获取到token
            String token = request.getParameter("token");
            //使客户端浏览器，区分不同种类的数据，并根据不同的括号里的调用浏览器内不同的程序嵌入模块来处理相应的数据
            response.setContentType("application/json;charset=utf-8");
            //判断token码是否为空
            if (StringUtils.isEmpty(token)) {
                ResultData resultData = ResultData.createFail("token为空,鉴权失败");
                //因为这个类是boolean类型的，我们可以使用response向前段传递一个类似于json字符串的值
                response.getWriter().write(JSON.toJSONString(resultData));
                //false:请求被拦截
                return false;
            }
            //判断token在全局的hashMap能不能找到对应的用户信息
            /**
             * 现在是把token放入Redis中，并且通过JSON.parseObject是将Json字符串转化为相应的对象
             */
            SysUser sysUser = JSON.parseObject(redisUtil.get(token), SysUser.class);
            if (sysUser == null) {
                ResultData resultData = ResultData.createFail("token不存在,鉴权失败");
                //因为这个类是boolean类型的，我们可以使用response向前段传递一个类似于json字符串的值
                response.getWriter().write(JSON.toJSONString(resultData));
                //false:请求被拦截
                return false;
            }
        }
        return true;
        /**
         * 写完之后我们需要将这个拦截器注册到spring当中   所以继续创建一个config-->webConfig
         */
    }

    //请求处理中
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    //处理完成请求
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }
}
